﻿using System.Data;
using System.Data.SqlClient;
using System.Xml;

namespace Symantec.DataFactories
{
    /// <summary>
    /// Represents a set of methods for creating instances of the System.Data.SqlClient
    /// providor's implementation of the data source classes.
    /// </summary>
    public sealed class SqlClientDataFactory : IDataFactory
    {
        #region Member variables
        private SqlCommand _command;
        private SqlConnection _connection;
        private SqlDataAdapter _dataAdapter;
        #endregion

        #region Private constants
        private const bool SupportsXmlreader = true;
        #endregion

        /// <summary>
        /// Initializes a new instance of a Symantec.DataFactories.SqlClientFactory class.
        /// </summary>
        private SqlClientDataFactory() { }

        /// <summary>
        /// Gets an instance of the IDataFactory. This can be used to retrieve strongly 
        /// typed data objects.
        /// </summary>
        public static IDataFactory Instance
        {
            get
            {
                return new SqlClientDataFactory();
            }
        }

        #region IDataFactory Members
        /// <summary>
        /// Creates a new IDbCommand object.
        /// </summary>
        /// <returns>
        /// A new, strongly typed instance of IDbCommand.
        /// </returns>
        public IDbCommand CreateCommand()
        {
            if (_connection == null)
                _connection = new SqlConnection();

            return _command ?? (_command = _connection.CreateCommand());
        }

        /// <summary>
        /// Creates a new IDbConnection object.
        /// </summary>
        /// <returns>
        /// A new, strongly typed instance of IDbConnection.
        /// </returns>
        public IDbConnection CreateConnection()
        {
            return _connection ?? (_connection = new SqlConnection());
        }

        /// <summary>
        /// Creates a new IDbDataAdapter object.
        /// </summary>
        /// <returns>
        /// A new, strongly typed instance of IDbDataAdapter.
        /// </returns>
        public IDataAdapter CreateDataAdapter()
        {
            if (_dataAdapter == null)
                _dataAdapter = new SqlDataAdapter();
            _dataAdapter.SelectCommand = _command;
            return _dataAdapter;
        }

        /// <summary>
        /// Use to execute the command and return a System.Xml.XmlReader object as IDbCommand does
        /// not support ExecuteXmlReader().
        /// </summary>
        /// <returns>
        /// Returns a System.Xml.XmlReader object.
        /// </returns>
        public XmlReader ExecuteXmlReader()
        {
            return _command.ExecuteXmlReader();
        }

        /// <summary>
        /// Check if this IDataFactory class supports System.Xml.XmlReader as not all IDataFactory 
        /// implementations do.
        /// </summary>
        public bool SupportsXmlReader
        {
            get { return SupportsXmlreader; }
        }

        /// <summary>
        /// Use to execute the command and return an IDataReader object.
        /// </summary>
        /// <returns>
        /// Returns an IDataReader object.
        /// </returns>
        public IDataReader ExecuteReader()
        {
            return _command.ExecuteReader();
        }

        /// <summary>
        /// Use to execute the command and fill a supplied DataSet object with the query results,
        /// returning the number of rows added to the DataSet.
        /// </summary>
        /// <param name="result">
        /// DataSet object to fill.
        /// </param>
        /// <returns>
        /// Returns the count of rows added to the DataSet.
        /// </returns>
        public int Fill(DataSet result)
        {
            return _dataAdapter.Fill(result);
        }
        #endregion
    }
}
